package com.gridmobi.xrtb.job;


import com.alibaba.fastjson.JSON;
import com.gridmobi.xrtb.domain.dsp.DspCreativeBanner;
import com.gridmobi.xrtb.domain.dsp.DspCreativeNative;
import com.gridmobi.xrtb.domain.dsp.DspCreativeVideo;
import com.gridmobi.xrtb.model.alg.*;
import com.gridmobi.xrtb.model.rtb.Creative;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
@Slf4j
public class SourceManager {
    Map<Integer, List<Creative>> imgSource;
    Map<Integer, List<Creative>> videoSource;
    Map<Integer, List<NativeAdWrapper>> nativeSource;


    public void syncImgSource(List<DspCreativeBanner> list) {
        System.out.println("SourceManager.syncImgSource");
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        Map<Integer, List<Creative>> tmp = new HashMap<>();
        for (DspCreativeBanner dspCreativeBanner : list) {
            List<Creative> creatives = tmp.get(dspCreativeBanner.getCid());
            if (CollectionUtils.isEmpty(creatives)) {
                creatives = new ArrayList<>();
                tmp.put(dspCreativeBanner.getCid(), creatives);
            }
            Creative c = convert(dspCreativeBanner);
            creatives.add(c);
        }

        imgSource = tmp;

        log.info("imgSource = {}", JSON.toJSONString(imgSource));
    }

    private Creative convert(DspCreativeBanner dspCreativeBanner) {
        Creative creative = new Creative();
        creative.setId(dspCreativeBanner.getId() + "");
        creative.setUrl(dspCreativeBanner.getWeburl());
        creative.setW(dspCreativeBanner.getW());
        creative.setH(dspCreativeBanner.getH());

        return creative;
    }


    public void syncVideoSource(List<DspCreativeVideo> list) {
        System.out.println("SourceManager.syncVideoSource");
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        Map<Integer, List<Creative>> tmp = new HashMap<>();
        for (DspCreativeVideo dspCreativeVideo : list) {
            List<Creative> creatives = tmp.get(dspCreativeVideo.getCid());
            if (CollectionUtils.isEmpty(creatives)) {
                creatives = new ArrayList<>();
                tmp.put(dspCreativeVideo.getCid(), creatives);
            }
            Creative c = convert(dspCreativeVideo);
            creatives.add(c);
        }

        videoSource = tmp;
        log.info("videoSource = {}", JSON.toJSONString(videoSource));

    }

    private Creative convert(DspCreativeVideo dspCreativeVideo) {
        Creative creative = new Creative();
        creative.setId(dspCreativeVideo.getId() + "");
        creative.setUrl(dspCreativeVideo.getWeburl());
        creative.setW(dspCreativeVideo.getW());
        creative.setH(dspCreativeVideo.getH());
        creative.setVideoduration(dspCreativeVideo.getMinduration());

        return creative;
    }

    public void syncNativeSource(List<DspCreativeNative> list) {
        System.out.println("SourceManager.syncNativeSource");
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        Map<Integer, List<NativeAdWrapper>> tmp = new HashMap<>();
        for (DspCreativeNative dspCreativeNative : list) {
            List<NativeAdWrapper> creatives = tmp.get(dspCreativeNative.getCid());
            if (CollectionUtils.isEmpty(creatives)) {
                creatives = new ArrayList<>();
                tmp.put(dspCreativeNative.getCid(), creatives);
            }
            NativeAd n = convert(dspCreativeNative);
            NativeAdWrapper nativeAdWrapper = new NativeAdWrapper(n, dspCreativeNative.getId().intValue());
            creatives.add(nativeAdWrapper);
        }

        nativeSource = tmp;
        log.info("nativeSource = {}", JSON.toJSONString(nativeSource));
    }

    private NativeAd convert(DspCreativeNative dspCreativeNative) {
        NativeAd nativeAd = new NativeAd();
        Asset[] assets = new Asset[4];
        nativeAd.setAssets(assets);
        // title
        Asset assetTitle = new Asset();
        Title title = new Title();
        title.setText(dspCreativeNative.getTitle());
        assetTitle.setTitle(title);
        assets[0] = assetTitle;
        // icon
        Asset assetIcon = new Asset();
        Image imgIcon = new Image();
        assetIcon.setImg(imgIcon);
        imgIcon.setType(ImageAssetType.ICON.getValue());
        imgIcon.setUrl(dspCreativeNative.getIconweburl());
        imgIcon.setW(dspCreativeNative.getIconw());
        imgIcon.setH(dspCreativeNative.getIconh());
        assets[1] = assetIcon;
        // big image
        Asset assetImage = new Asset();
        Image imgImage = new Image();
        assetImage.setImg(imgImage);
        imgImage.setType(ImageAssetType.MAIN.getValue());
        imgImage.setUrl(dspCreativeNative.getImgweburl());
        imgImage.setW(dspCreativeNative.getImgw());
        imgImage.setH(dspCreativeNative.getImgh());
        assets[2] = assetImage;
        // data
        Asset dataAsset = new Asset();
        Data data = new Data();
        dataAsset.setData(data);
        data.setType(DataAssetType.DESC.getValue());
        data.setValue(dspCreativeNative.getAddesc());
        assets[3] = dataAsset;

        return nativeAd;
    }

    public Creative getImg(Integer cid, Integer w, Integer h) {

        if (CollectionUtils.isEmpty(imgSource)) {
            return null;
        }
        List<Creative> creatives = imgSource.get(cid);
        if (CollectionUtils.isEmpty(creatives)) {
            return null;
        }
        List<Creative> matchedCreative = new ArrayList<>();
        for (Creative creative : creatives) {
            if ((creative.getW() % w == 0 && creative.getH() % h == 0) || (w % creative.getW() == 0 && h % creative.getH() == 0)) {
                matchedCreative.add(creative);
            }
        }

        Random random = new Random();
        if (CollectionUtils.isEmpty(matchedCreative)) {
            return creatives.get(random.nextInt(creatives.size()));
        }
        int i = random.nextInt(matchedCreative.size());
        return matchedCreative.get(i);
    }

    public Creative getVideo(Integer cid, Integer w, Integer h) {
        if (CollectionUtils.isEmpty(videoSource)) {
            return null;
        }

        List<Creative> creatives = videoSource.get(cid);
        if (CollectionUtils.isEmpty(creatives)) {
            return null;
        }
        List<Creative> matchedCreative = new ArrayList<>();
        for (Creative creative : creatives) {
            if ((creative.getW() % w == 0 && creative.getH() % h == 0) || (w % creative.getW() == 0 && h % creative.getH() == 0)) {
                matchedCreative.add(creative);
            }
        }

        Random random = new Random();
        if (CollectionUtils.isEmpty(matchedCreative)) {
            return creatives.get(random.nextInt(creatives.size()));
        }
        int i = random.nextInt(matchedCreative.size());
        return matchedCreative.get(i);
    }

    public NativeAdWrapper getNative(Integer cid, Integer w, Integer h) {
        if (CollectionUtils.isEmpty(nativeSource)) {
            return null;
        }

        List<NativeAdWrapper> nativeAds = nativeSource.get(cid);
        if (CollectionUtils.isEmpty(nativeAds)) {
            return null;
        }

        List<NativeAdWrapper> matchedCreative = new ArrayList<>();
        for (NativeAdWrapper nativeAdWrapper : nativeAds) {
            Image img = nativeAdWrapper.getNativeAd().getAssets()[2].getImg();
            if ((img.getW() % w == 0 && img.getH() % h == 0) || (w % img.getW() == 0 && h % img.getH() == 0)) {
                matchedCreative.add(nativeAdWrapper);
            }
        }
        Random random = new Random();
        if (CollectionUtils.isEmpty(matchedCreative)) {
            return nativeAds.get(random.nextInt(nativeAds.size()));
        }
        int i = random.nextInt(matchedCreative.size());
        return matchedCreative.get(i);
    }

}
